globvarRule = 0
globvarIgnore = 0
globvarConcat = False
globvarFirstRule = False #variable que se utiliza para saber si es el comienzo de una regla
import re
from collections import namedtuple

class Inicial():
    pass

class inicial(namedtuple('Inicial','listaB'),Inicial):
    # def __init__(self,listaB):
    #    self.listaB = listaB    
        
    def unparse(self):
        return self.listaB.unparse()
    
    def genprec(self,lexemas):
        return self.listaB.genprec(lexemas)

    def genIgnore(self ):
        return self.listaB.genIgnore( )
        
    def genClass(self,dic):
        salida = self.listaB.genClass (dic)
        return salida

    def genLex(self ):
        return self.listaB.genLex( )

    def genRules(self,lexemas ):
        salida = self.listaB.genRules(lexemas )+'\n'
        global globvarConcat
        if (globvarConcat==True): 
            salida = salida + '\ndef __concat__(x,y):\n\treturn (x if type( x ) is list else [x]) + (y if type( y ) is list else [y])'
        return salida
    
    def checkType(self):
        return self.listaB.checkType()
    
    def getCat(self):
        return self.listaB.getCat()
    
    def checkNT(self,lCat):
        return self.listaB.checkNT(lCat)

class ListaBloques():
    pass

#    'listaBloques:INICIO cat listaBloques'
    #t[0] = listaBloques(t[2],t[3])        
class listaBloques(namedtuple('listaBloques','cat listaB'),ListaBloques):
    #def __init__(self, cat,listaB):
    #    self.cat = cat
    #    self.listaB = listaB    
        
    def unparse(self):
        return '%start '+self.cat.unparse()+self.listaB.unparse()
    
    def genprec(self,lexemas):
        return self.listaB.genprec(lexemas)

    def genIgnore(self ):
        return self.listaB.genIgnore( )
        
    def genClass(self,dic):
        self.cat.genClass(dic) 
        self.listaB.genClass (dic)

    def genLex(self ):
        return self.cat.genLex( )+self.listaB.genLex( )

    def genRules(self,lexemas ):
        salida = self.cat.genRules(lexemas,  )+''+self.listaB.genRules(lexemas )+'\n'
        return salida
    
    def checkType(self):
        return self.cat.checkType() and self.listaB.checkType()
    
    def getCat(self):
        return  self.cat.getCat() + self.listaB.getCat()

    def checkNT(self,lCat):
        return self.cat.checkNT(lCat) and self.listaB.checkNT(lCat)
     
    # 'listaBloques:cat listaBloques'
    #t[0] = listaBloques1(t[1],t[2])
class listaBloques1(namedtuple('listaBloques1','cat listaB'),ListaBloques):
    #def __init__(self, cat,listaB):
    #    self.cat = cat
    #    self.listaB = listaB      
        
    def unparse(self):
        return self.cat.unparse()+self.listaB.unparse()
    
    def genprec(self,lexemas):
        return self.listaB.genprec(lexemas)

    def genIgnore(self ):
        return self.listaB.genIgnore( )

    def genClass(self,dic):
        self.cat.genClass(dic)
        self.listaB.genClass(dic)

    def genLex(self ):
        return self.cat.genLex( )+self.listaB.genLex( )

    def genRules(self,lexemas ):
        salida=self.cat.genRules(lexemas ) + self.listaB.genRules(lexemas )+'\n'
        return salida
    
    def checkType(self):
        return self.cat.checkType() and self.listaB.checkType()
    
    def getCat(self):
        return  self.cat.getCat() + self.listaB.getCat()

    def checkNT(self,lCat):
        return self.cat.checkNT(lCat) and self.listaB.checkNT(lCat)
    
    #'listaBloques:prec listaBloques'
    #t[0] = listaBloques2(t[1],t[2])
class listaBloques2(namedtuple('listaBloques2','prec listaB'),ListaBloques):
    #def __init__(self, prec,listaB):
    #    self.prec = prec
    #    self.listaB = listaB      
        
    def unparse(self):
        return self.prec.unparse()+self.listaB.unparse()
    
    def genprec(self,lexemas):
        salida1 =self.prec.genprec(lexemas)
        salida2 =self.listaB.genprec(lexemas) 
        return  salida1 + salida2

    def genIgnore(self ):
        return self.listaB.genIgnore( )
    
    def genClass(self,dic):
        self.listaB.genClass(dic)

    def genLex(self ):
        return self.listaB.genLex( )

    def genRules(self,lexemas ):
        salida =self.listaB.genRules(lexemas )
        return salida
    
    def checkType(self):
        return self.prec.checkType() and self.listaB.checkType()
   
    def getCat(self):
        return  self.listaB.getCat()

    def checkNT(self,lCat):
        return self.listaB.checkNT(lCat)

    #listaBloques : prec     
class listaBloques8(namedtuple('listaBloques8','prec'),ListaBloques): 
    #def __init__(self,prec):
    #    self.prec = prec
        
    def unparse(self):
        return self.prec.unparse()
    
    def genprec(self,lexemas):
        return self.prec.genprec(lexemas) 

    def genClass(self,dic):
        pass

    def genLex(self ):
        return []

    def genRules(self,lexemas ):
        salida = ''
        return salida
    
    def checkType(self):
        return self.prec.checkType()
    
    def getCat(self):
        return  []
    
    def checkNT(self,lCat):
        return True
 
    #'listaBloques:ignorables listaBloques'
    #t[0] = listaBloques3(t[1],t[2])
class listaBloques3(namedtuple('listaBloques1','ignorables listaB'),ListaBloques):
    #def __init__(self, ignorables,listaB):
    #    self.ignorables = ignorables
    #    self.listaB = listaB
        
    def unparse(self):
        return self.ignorables.unparse()+self.listaB.unparse()
    
    def genprec(self,lexemas):
        return self.listaB.genprec(lexemas)

    def genIgnore(self ):
        return self.ignorables.genIgnore( )
    
    def genClass(self,dic):
        self.listaB.genClass(dic)

    def genLex(self ):
        return self.listaB.genLex( )

    def genRules(self,lexemas ):
        salida = self.listaB.genRules(lexemas )
        return salida
    
    def checkType(self):
        return self.ignorables.checkType() and self.listaB.checkType()
    
    def getCat(self):
        return  self.listaB.getCat()
    
    def checkNT(self,lCat):
        return self.listaB.checkNT(lCat)

    #'listaBloques:cat'
    #t[0] = listaBloques4(t[1])
class listaBloques4(namedtuple('listaBloques4','cat'),ListaBloques):
    #def __init__(self, cat):
    #    self.cat = cat
        
    def unparse(self):
        return self.cat.unparse()
    
    def genprec(self,lexemas):
        return ''

    def genIgnore(self ):
        return ''

    def genClass(self,dic):
        self.cat.genClass(dic)

    def genLex(self ):
        return self.cat.genLex( )

    def genRules(self,lexemas ):
        salida = self.cat.genRules(lexemas )
        return salida
    
    def checkType(self):
        return self.cat.checkType()

    def getCat(self):
        return  self.cat.getCat()
    
    def checkNT(self,lCat):
        return self.cat.checkNT(lCat)

    #'listaBloques:ignorables'
    #t[0] = listaBloques6(t[1])
class listaBloques6(namedtuple('listaBloques1','ignorables'),ListaBloques):
    #def __init__(self, ignorables):
    #    self.ignorables = ignorables
        
    def unparse(self):
        return self.ignorables.unparse()
    
    def genprec(self,lexemas):
        return ''

    def genIgnore(self ):
        return self.ignorables.genIgnore( )
    
    def genClass(self,dic):
        return ''

    def genLex(self ):
        return []

    def genRules(self,lexemas ):
        salida = ''
        return salida
    
    def checkType(self):
        return self.ignorables.checkType()

    def getCat(self):
        return  []
    
    def checkNT(self,lCat):
        return True
    
    #'listaBloques:INICIO cat'
    #t[0] = listaBloques7(t[2])
class listaBloques7(namedtuple('listaBloques7','cat'),ListaBloques):
    #def __init__(self, cat):
    #    self.cat = cat
        
    def unparse(self):
        return '%start ' + self.cat.unparse()
    
    def genprec(self,lexemas):
        return ''

    def genIgnore(self ):
        return ''
    
    def genClass(self,dic):
        self.cat.genClass(dic) 

    def genLex(self ):
        return self.cat.genLex( )

    def genRules(self,lexemas):
        salida = self.cat.genRules(lexemas )
        return salida
    
    def checkType(self):
        return self.cat.checkType()
    
    def getCat(self):
        return  self.cat.getCat()

    def checkNT(self,lCat):
        return self.cat.checkNT(lCat)

class Prec():
    pass

    #'prec:RIGHT listat'
    #t[0] = prec(t[2])
class prec(namedtuple('precR','listaT'),Prec):
    #def __init__(self, listaT):
    #    self.listaT = listaT    
        
    def unparse(self):
        return '%RIGHT '+self.listaT.unparse()+';'
    
    def genprec(self,lexemas):
        return '('"'"'right'"'"+self.listaT.genprec(lexemas)+'),'

    def genLex(self,cant):
        return []

    def genRules(self,lexemas):
        salida = ''
        return salida
    
    def checkType(self):
        return self.listaT.checkType()
    
    #'prec:LEFT listat'
    #t[0] = prec1(t[2])
class prec1(namedtuple('precL','listaT'),Prec):
    #def __init__(self, listaT):
    #    self.listaT = listaT     
    
    def unparse(self):
        return '%LEFT '+self.listaT.unparse()+';'
    
    def genprec(self,lexemas):
        return '('"'"'left'"'"+self.listaT.genprec(lexemas)+'),'

    def genLex(self ):
        return []    
    
    def genRules(self,lexemas):
        salida = ''
        return salida
    
    def checkType(self):
        return self.listaT.checkType()
    
    #'prec:NONASOC listat'
    #t[0] = prec2(t[2])    
class prec2(namedtuple('precN','listaT'),Prec):
    #def __init__(self, listaT):
    #    self.listaT = listaT 
        
    def unparse(self):
        return '%NONASSOC '+self.listaT.unparse()+';'

    def genprec(self,lexemas):
        return '('"'"'nonassoc'"'"+self.listaT.genprec(lexemas)+'),'

    def genLex(self ):
        return []

    def genRules(self,lexemas):
        salida = ''
        return salida
    
    def checkType(self):
        return self.listaT.checkType()
    
###############################################################################################################################

class ListaT():
    pass

    #'listat: terminal'
    #t[0] = listat(t[1])
  
class listat(namedtuple('listat','terminal'),ListaT):
    #def __init__(self, terminal):
    #    self.terminal = terminal
        
    def unparse(self):
        return self.terminal.unparse()     
    
    def genprec(self,lexemas):
        return self.terminal.genprec(lexemas)
    
    def genIgnore(self ):
        salida = self.terminal.genIgnore( )
        return salida    

    def genLex(self ):
        return self.terminal.genLex( )
    
    def genRules(self,lexemas):
        salida = 'LISTAT'+'\n'
        return salida
    
    def checkType(self):
        return self.terminal.checkType()

    #'listat: terminal listat'
    #t[0] = listat1(t[1],t[2])
class listat1(namedtuple('listat1','terminal listaT'),ListaT):
    #def __init__(self, terminal,listaT):
    #    self.terminal = terminal
    #    self.listaT = listaT
        
    def unparse(self):
        return self.terminal.unparse() + self.listaT.unparse()

    def genprec(self,lexemas):
        return self.terminal.genprec(lexemas) + self.listaT.genprec(lexemas)

    def genIgnore(self ):
        salida = self.terminal.genIgnore( )  + self.listaT.genIgnore( )
        return salida

    def genLex(self ):
        return self.terminal.genLex()+self.listaT.genLex( )

    def genRules(self,lexemas):
        salida = 'LISTAT 1'+'\n'
        return salida
    
    def checkType(self):
        return self.terminal.checkType() and self.listaT.checkType()

###############################################################################################################################
class Ignorable():
    pass
    #'ignorable: IGNORABLE listat'
    #t[0] = ignorable(t[2])
class ignorable(namedtuple('ignorable','listaT'),Ignorable):
    #def __init__(self, listaT):
    #    self.listaT = listaT
        
    def genIgnore(self ):
        return self.listaT.genIgnore( )
    
    def unparse(self):
        return 
    
    def checkType(self):
        return self.listaT.checkType()


###############################################################################################################################

class Cat():
    pass
    
    #'cat : IDNT ENTONCES ID DPUNTO stmts PCOMA'
    #t[0] = cat(t[1],t[3],t[5])
class cat(namedtuple('cat','idnt id1 sents'),Cat):
    #def __init__(self, idnt,id1,sents):
    #    self.idnt = idnt
    #    self.id1 = id1
    #    self.sents = sents     
        
    def unparse(self):
        return self.idnt+' > '+self.id1+' : '+self.sents.unparse()+';'

    def genClass(self,dic):
        if not(self.id1 in dic):
            dic[self.id1]=[]
        self.sents.genClass(dic,self.id1)
    
    def genLex(self ):
        return self.sents.genLex( )
 
    def genRules(self,lexemas ):
        salida =self.sents.genRules(lexemas ,self.idnt)
        return salida
    
    def checkType(self):
        return self.sents.checkType()
    
    def getCat(self):
        return[self.idnt]
    
    def checkNT(self,lCat):
        return self.sents.checkNT(lCat) 

    #'cat : IDNT ENTONCES ACORCH ID CCORCH DPUNTO stmts PCOMA'
    #t[0] = cat1(t[1],t[4],t[7])    
class cat1(namedtuple('cat1','idnt id1 sents'),Cat):
    #def __init__(self, idnt,id1,sents):
    #    self.idnt = idnt
    #    self.id1 = id1
    #    self.sents = sents

    def unparse(self):
        return self.idnt+' > ['+self.id1+'] : '+self.sents.unparse()+';'

    def genClass(self,dic):
        if not(self.id1 in dic):
            dic[self.id1]=[]
        self.sents.genClass(dic,self.id1)

    def genLex(self ):
        return self.sents.genLex( )

    def genRules(self,lexemas ):
        salida =self.sents.genRules(lexemas ,self.idnt)
        return salida
    
    def checkType(self):
        return self.sents.checkType()

    def getCat(self):
        return[self.idnt]
 
    def checkNT(self,lCat):
        return self.sents.checkNT(lCat) 
 
###############################################################################################################################

class Stmts():
    pass
  
    #'stmts : stmt'
    #t[0] = stmts(t[1])
class stmts(namedtuple('stmts','sent'),Stmts):
    #def __init__(self,sent):
    #    self.sent = sent     
 
    def unparse(self):    
        return  self.sent.unparse() 
 
    def genClass(self,dic,idCat):
        self.sent.genClass(dic,idCat)

    def genLex(self ):
        return self.sent.genLex( )
    
    def genRules(self,lexemas ,idnt):
        salida = self.sent.genRules(lexemas ,idnt)
        return salida
    
    def checkType(self):
        return self.sent.checkType()

    def checkNT(self,lCat):
        return self.sent.checkNT(lCat) 
   
    #'stmts : stmt PIPE stmts'
    #t[0] = stmts1(t[1],t[3])     
class stmts1(namedtuple('stmts1','sent sents'),Stmts):
    #def __init__(self, sent,sents):
    #    self.sent = sent
    #    self.sents = sents         

    def unparse(self):    
        return  self.sent.unparse()+' | '+self.sents.unparse() 

    def genClass(self,dic,idCat):
        self.sent.genClass(dic,idCat)
        self.sents.genClass(dic,idCat)
     
    def genLex(self ):
        return self.sent.genLex( )+self.sents.genLex( )
    
    def genRules(self,lexemas ,idnt):
        salida = self.sent.genRules(lexemas ,idnt)####aca
        salida= salida + self.sents.genRules(lexemas ,idnt)
        return salida
    
    def checkType(self):
        return self.sent.checkType() and self.sents.checkType()

    def checkNT(self,lCat):
        return self.sent.checkNT(lCat) and self.sents.checkNT(lCat) 

###############################################################################################################################
class Stmt():
    pass 
 
    #'stmt : produccion ENTONCES accionsemantica'
    #t[0] = stmt(t[1],t[3])
class stmt(namedtuple('stmt','prod accion'),Stmt):
    #def __init__(self, prod,accion):
    #    self.prod = prod
    #    self.accion = accion

    def unparse(self):    
        return  self.prod.unparse()+' > '+self.accion.unparse()
    
    def genClass(self,dic,idCat):
        self.accion.genClass(dic,idCat)

    def genLex(self ):
        return self.prod.genLex() 

    def genRules(self,lexemas ,idnt):
        global globvarRule
        global globvarFirstRule
        globvarFirstRule=True        
        salida = '\ndef p_RULE00'+str(globvarRule)+'(p):'+'\t#'+idnt+':'+self.prod.unparse()+'>'+self.accion.unparse()+'\n'
        salida = salida+'\t"'+ self.prod.genRules(lexemas,idnt)+'"'+'\n'+'\tp[0] ='+ self.accion.genRules()+'\n'####
        globvarRule =globvarRule+1 
        return salida
    
    def checkType(self):
        produCheck=self.prod.checkType()  #Chequea las ER
        produ=self.prod.getType()
        acc=self.accion.getType(False)
        if produCheck==True:
            for elemento in acc:
                if(len(produ)<elemento):
                    print "Error - referencia no valida en la produccion: " + self.unparse()
                    return False
            return True  
        else:
            return False
        
    def checkNT(self,lCat):
        return self.prod.checkNT(lCat) 
    
    #'stmt : ENTONCES accionsemantica'
    #t[0] = stmt1(t[2])      
class stmt1(namedtuple('stmt1','accion'),Stmt):
    
    #def __init__(self,accion):
    #    self.accion = accion
    
    def unparse(self):
        return self.accion.unparse() 

    def genClass(self,dic,idCat):
        self.accion.genClass(dic,idCat)

    def genLex(self ):
        return []

    def genRules(self,lexemas,idnt):
        #salida = 'STMT 1 '+self.accion.genRules()+'\n'
        global globvarRule
        
        salida = '\ndef p_RULE00'+str(globvarRule)+'(p):'+'\t#'+idnt+': >'+self.accion.unparse()+'\n'
        salida = salida+'\t"'+ idnt+' : " '+'\n' +'\tp[0] = '+self.accion.genRules()+'\n'####
        globvarRule =globvarRule+1         
        return salida
    
    def checkType(self):
        acc=self.accion.getType(True)
        if not acc:
            return True  
        else:
            return False

    def checkNT(self,lCat):
        return True

###############################################################################################################################

class Produccion():
    pass
    #'produccion: IDNT'
    #t[0] = produccion(t[1])
class produccion (namedtuple('produccion','idnt'),Produccion):
    #def __init__(self, idnt):
    #    self.idnt = idnt

    def unparse(self):    
        return  self.idnt

    def genLex(self ):
        return []

    def genRules(self,lexemas,idnt):
        salida =idnt+' : '+self.idnt
        return salida
    
    def getType(self):
        return ['NT']

    def checkType(self):
        return True
    
    def checkNT(self,lCat):
        if self.idnt in lCat:
            return True
        else:
            return False

#    'produccion: terminal'
#   t[0] = produccion1(t[1])
class produccion1 (namedtuple('produccion1','term'),Produccion):
    #def __init__(self, term):
    #    self.term = term
 
    def unparse(self):    
        return  self.term.unparse()
       
    def genLex(self ):
        return self.term.genLex( )

    def genRules(self,lexemas,idnt):
        salida =idnt+' : '+ self.term.genRules(lexemas)
        return salida
    
    def getType(self):
        return self.term.getType()

    def checkType(self):
        return self.term.checkType()

    def checkNT(self,lCat):
        return True
#  'produccion: produccion IDNT'
# t[0] = produccion2(t[1],t[2])
class produccion2 (namedtuple('produccion2','prod idnt'),Produccion):
    #def __init__(self, prod,idnt):
    #    self.prod = prod
    #    self.idnt = idnt

    def unparse(self):    
        return  self.prod.unparse()+' '+self.idnt

    def genLex(self ):
        return self.prod.genLex( )

    def genRules(self,lexemas,idnt):
        salida = self.prod.genRules(lexemas,idnt)+' '+self.idnt
        return salida
    
    def getType(self):
        return self.prod.getType() + ['NT']   

    def checkType(self):
        return self.prod.checkType()

    def checkNT(self,lCat):
        if self.idnt in lCat:
            return self.prod.checkNT(lCat)
        else:
            return False

    #'produccion: produccion terminal'
    #t[0] = produccion3(t[1],t[2])
class produccion3 (namedtuple('produccion3','prod term'),Produccion):
    #def __init__(self, prod,term):
    #    self.prod = prod
    #    self.term = term

    def unparse(self):    
        return  self.prod.unparse()+' '+self.term.unparse()

    def genLex(self ):
        return self.prod.genLex( )+self.term.genLex( )

    def genRules(self,lexemas,idnt):
        salida = self.prod.genRules(lexemas,idnt)+' '+self.term.genRules(lexemas)
        return salida
    
    def getType(self):
        return self.prod.getType() + self.term.getType()   

    def checkType(self):
        return self.prod.checkType() and self.term.checkType()   

    def checkNT(self,lCat):
        return self.prod.checkNT(lCat)

###############################################################################################################################

class Terminal():
    pass
    
    #'terminal: ER'
    #t[0] = terminal(t[1])
class terminal(namedtuple('terminal','er'),Terminal):
    #def __init__(self, er):
    #    self.er = er

    def unparse(self):    
        return  str(self.er)

    def genprec(self,lexemas):
        expR = self.er[1:len(self.er)-1]
        try:
            salida=",'" + lexemas[expR] + "'"
            return salida
        except:
            print "La expresion regular "+expR+" definida en la lista de precedencias no es un token valido"
            return ""
    
    def genIgnore(self ):
        global globvarIgnore
        salida='t_ignore_'+str(globvarIgnore)+' = r'+"'"+self.er+"'"+'\n'
        globvarIgnore = globvarIgnore +1
        return salida

    def genLex(self ):
        return [self.er]

    def genRules(self,lexemas):
        expR = self.er[1:len(self.er)-1]
        salida = lexemas[expR]
        return salida

    def getType(self):
        return ['T']   
    
    def checkType(self):
        try:
            num = len(self.er)
            valor = self.er[1:num-1]
            re.compile(valor)            
            return True
        except Exception as exce:
            print "Error - La expresion regular " + self.er +" no es valida"
            print exce
            return False

    #'terminal: ST'
    #t[0] = terminal1(t[1])
class terminal1(namedtuple('terminal1','st'),Terminal):
    #def __init__(self, st):
    #    self.st = st    

    def unparse(self):    
        return  self.st
    
    def genprec(self,lexemas):
        simboloTerminal =self.st[1:len(self.st)-1]
        try:
            salida = ",'" + lexemas[simboloTerminal] + "'"
            return salida
        except:
            print "El simbolo terminal "+simboloTerminal+" definido en la lista de precedencias no es un token valido"
            return ""

    def genIgnore(self ):
        global globvarIgnore
        segundaComilla = self.st.find("'",2)
        simbolo = self.st[1:segundaComilla]
        if (simbolo.find(".")==-1 and simbolo.find("^")==-1 and simbolo.find("$")==-1 and simbolo.find("*")==-1 and simbolo.find("+")==-1 and simbolo.find("?")==-1 and simbolo.find("{")==-1 and simbolo.find("}")==-1 and simbolo.find("[")==-1 and simbolo.find("]")==-1 and simbolo.find("'\'")==-1 and simbolo.find("|")==-1 and simbolo.find("(")==-1 and simbolo.find(")")==-1):
            salida='t_ignore_'+str(globvarIgnore)+" = r'"+simbolo+"'\n"
        else:
            salida='t_ignore_'+str(globvarIgnore)+" = r'\\"+simbolo+"'\n"
        globvarIgnore = globvarIgnore +1
        return salida
    
    def genLex(self ):
        return [self.st]
    
    def genRules(self,lexemas):
        simboloTerminal =self.st[1:len(self.st)-1]
        salida = lexemas[simboloTerminal]
        return salida
    
    def getType(self):
        return ['T']   

    def checkType(self):
        return True
                
###############################################################################################################################

    

class AccionSemantica():
    pass

 
    #'accionsemantica : APAREN ID CPAREN'
    #t[0] = accionSemantica1(t[2])
class accionsemantica1(namedtuple('accionsemantica1','id1'),AccionSemantica):
    #def __init__(self, id1):
    #    self.id1 = id1

    def unparse(self):    
        return '('+self.id1+')'

    def genClass(self,dic,idCat):
        dic[self.id1]=[[idCat]]

    def genRules(self):
        salida = self.id1+'() \n'
        return salida
    
    def getType(self, prodVacia):
        if prodVacia:
            return []
        else:
            return [1]
            
    #'accionsemantica : nodo'
    #t[0] = accionSemantica2(t[1])
class accionsemantica2(namedtuple('accionsemantica2','nodo'),AccionSemantica):
    #def __init__(self, nodo):
    #    self.nodo = nodo
    
    def unparse(self):    
        return  self.nodo.unparse()

    def genClass(self,dic,idCat):
        self.nodo.genClass(dic,idCat)

    def genRules(self):
        salida = self.nodo.genRules()
        return salida
    
    def getType(self,prodVacia):
        return self.nodo.getType(prodVacia)    
        
    #'accionsemantica : listanodos'
    #t[0] = accionSemantica2(t[1])
class accionsemantica3(namedtuple('accionsemantica3','listaN'),AccionSemantica):
    #def __init__(self, listaN):
    #    self.listaN = listaN
    
    def unparse(self):    
        return  self.listaN.unparse()

    def genClass(self,dic,idCat):
        self.listaN.genClass(dic,idCat)

    def genRules(self):
        salida = self.listaN.genRules()
        return salida
    
    def getType(self,prodVacia):
        return self.listaN.getType(prodVacia)    

    
###############################################################################################################################

class ListaNodos():
    pass

    #'listanodos : nodo DPUNTO nodo
    #t[0] = listanodos(t[1],t[3])
class listanodos(namedtuple('listanodos','nodo1 nodo2'),ListaNodos):
    #def __init__(self, nodo1, nodo2):
    #    self.nodo1 = nodo1
    #    self.nodo2 = nodo2

    def unparse(self):    
        return  self.nodo1.unparse()+" : "+self.nodo2.unparse()


    def genClass(self,dic,idCat):
        self.nodo1.genClass(dic,idCat)
        self.nodo2.genClass(dic,idCat)

    def genRules(self):
        salida = '__concat__('+ self.nodo1.genRules()+','+self.nodo2.genRules()+')'
        global globvarConcat
        globvarConcat = True
        return salida

    def getType(self,prodVacia):
        return self.nodo1.getType(prodVacia) + self.nodo2.getType(prodVacia)
    
    
    #'listanodos : listanodos DPUNTO nodo
    #t[0] = listanodos1(t[1],t[3])    
class listanodos1(namedtuple('listanodos1','listaN nodo'),ListaNodos):
    #def __init__(self, listaN, nodo):
    #    self.listaN = listaN
    #    self.nodo = nodo

    def unparse(self):    
        return  self.listaN.unparse()+" : "+self.nodo.unparse()

    def genClass(self,dic,idCat):
        self.listaN.genClass(dic,idCat)
        self.nodo.genClass(dic,idCat)

    def genRules(self):
        salida = '__concat__('+ self.listaN.genRules()+','+self.nodo.genRules()+')'
        global globvarConcat
        globvarConcat = True
        return salida

        def getType(self,prodVacia):
            return self.listaN.getType(prodVacia) + self.nodo.getType(prodVacia)
    
    

###############################################################################################################################

class Nodo():
    pass

    #nodo:PESOS INTEGER
    #t[0] = nodo(t[2])
class nodo(namedtuple('nodo','entero'),Nodo):
    #def __init__(self,entero):
    #    self.entero = entero
    
    def unparse(self):    
        return  '$ '+str(self.entero)
    
    def genClass(self,dic,idCat):
        pass

    def genRules(self):
        salida='p['+str(self.entero)+']'
        return salida
    
    def getType(self,prodVacia):
        return [self.entero]
    
    #nodo:APAREN ID listaparm CPAREN
    #t[0] = nodo1(t[2],t[3])
class nodo1(namedtuple('nodo1','id1 listaP'),Nodo):        
    #def __init__(self,id1,listaP):
    #    self.id1 = id1
    #    self.listaP = listaP
    
    def unparse(self):    
        return  '('+ self.id1+' '+self.listaP.unparse()+')'

    def genClass(self,dic,idCat):
        if not(self.id1 in dic):
            dic[self.id1]=[[idCat]]
            self.listaP.genClass(dic,idCat,self.id1)

    def genRules(self):
        salida='('+self.id1+'('+self.listaP.genRules()+'))'
        return salida
    
    def getType(self,prodVacia):
        return self.listaP.getType(prodVacia)
   
    #nodo:ACORCH nodo CCORCH
    #t[0] = nodo2(t[2])
class nodo2(namedtuple('nodo2','nodo'),Nodo):        
    #def __init__(self,nodo):
    #    self.nodo = nodo

    def unparse(self):    
        return  '['+self.nodo.unparse()+']'

    def genClass(self,dic,idCat):
        self.nodo.genClass(dic,idCat)
    
    def genRules(self):
        salida = '['+self.nodo.genRules()+']'
        return salida
    
    def getType(self,prodVacia):
        return self.nodo.getType(prodVacia)

    #nodo:ACORCH CCORCH
    #t[0] = nodo3()
class nodo3(namedtuple('nodo3',''),Nodo):        
    # def __init__(self):
    #     pass
    
    def unparse(self):    
        return '[]'

    def genClass(self,dic,idCat):
        pass
    
    def genRules(self):
        salida = '[]'
        return salida

    def getType(self,prodVacia):
        return []

 
class ListaParm():
    pass      

    #'listaparm : IDNT IGUAL nodo'
    #t[0] = ListaParm(t[1],t[4])
class listaparm(namedtuple('listaparm','idnt nodo'),ListaParm):
    #def __init__(self, idnt, nodo):
    #    self.idnt = idnt
    #    self.nodo = nodo
        
    def unparse(self):    
        return self.idnt + "=" + self.nodo.unparse()
    
    def genClass(self,dic,idCat,id1):
        a=dic[id1]
        if(len(a)==1):
            a.append([self.idnt])
        else:
            b=a[1]
            b.append(self.idnt) 
            a[1]=b
        dic[id1]=a
        self.nodo.genClass(dic,idCat)
    
    def genRules(self):
        salida = self.idnt+' = '+str(self.nodo.genRules())
        return salida
    
    def getType(self,prodVacia):
        return self.nodo.getType(prodVacia)
        
    #listaparm : IDNT IGUAL nodo listaparm'
    #t[0] = listaparm1(t[1],t[3],t[4])

class listaparm1(namedtuple('listaparm1','idnt nodo listaP'),ListaParm):
    #def __init__(self, idnt,nodo, listaP):
    #    self.idnt = idnt
    #    self.nodo = nodo
    #    self.listaP = listaP    
 
    def unparse(self):    
        return self.idnt + "=" + self.nodo.unparse()+' '+ self.listaP.unparse()

    def genClass(self,dic,idCat,id1):
        a=dic[id1]
        if(len(a)==1):
            a.append([self.idnt])
        else:
            b=a[1]
            b.append(self.idnt) 
            a[1]=b
        dic[id1]=a
        self.nodo.genClass(dic,idCat)
        self.listaP.genClass(dic,idCat,id1)
    
    def genRules(self):
        salida = self.idnt+' = '+self.nodo.genRules()+', '+ self.listaP.genRules()
        return salida
    
    def getType(self,prodVacia):
        return self.nodo.getType(prodVacia) + self.listaP.getType(prodVacia)    
    
    #'listaparm : IDNT IGUAL listanodos'
    #t[0] = ListaParm2(t[1],t[4])
class listaparm2(namedtuple('listaparm2','idnt listaN'),ListaParm):
    #def __init__(self, idnt, listaN):
    #    self.idnt = idnt
    #    self.listaN = listaN
    
    def unparse(self):    
        return self.idnt + "=" + self.listaN.unparse()

    def genClass(self,dic,idCat,id1):
        a=dic[id1]
        if(len(a)==1):
            a.append([self.idnt])
        else:
            b=a[1]
            b.append(self.idnt) 
            a[1]=b
        dic[id1]=a
        self.listaN.genClass(dic,idCat)
    
    def genRules(self):
        salida = self.idnt+' = ' + self.listaN.genRules()
        return salida
    
    def getType(self,prodVacia):
        return self.listaN.getType(prodVacia)
        
    #listaparm : IDNT IGUAL listanodos listaparm'
    #t[0] = listaparm1(t[1],t[3],t[4])
class listaparm3(namedtuple('listaparm3','idnt listaN listaP'),ListaParm):
    #def __init__(self, idnt,listaN, listaP):
    #    self.idnt = idnt
    #    self.listaN = listaN
    #    self.listaP = listaP    
 
    def unparse(self):    
        return self.idnt + "=$" + self.listaN.unparse()+' '+ self.listaP.unparse()

    def genClass(self,dic,idCat,id1):
        a=dic[id1]
        if(len(a)==1):
            a.append([self.idnt])
        else:
            b=a[1]
            b.append(self.idnt) 
            a[1]=b
        dic[id1]=a
        self.listaN.genClass(dic,idCat)
        self.listaP.genClass(dic,idCat,id1)
                    
    def genRules(self):
        salida = self.idnt+' = '+self.listaN.genRules()+', '+ self.listaP.genRules()
        return salida
    
    def getType(self,prodVacia):
        return self.listaN.getType(prodVacia) + self.listaP.getType(prodVacia)        